#include "vector3D.h"

namespace t2c2 {

Vector3D::Vector3D(void) : x(0.0), y(0.0) , z(0.0) 
{ }

Vector3D::Vector3D(const double _x, const double _y,const double _z) : x(_x), y(_y), z(_z) 
{ }

Vector3D::Vector3D(const Vector3D& _vector) : x(_vector.x) , y(_vector.y) , z(_vector.z) { }

Vector3D::~Vector3D(void) { }

double Vector3D::dot_product(const Vector3D& _vector) const {
	return x*_vector.x+ y*_vector.y+ z*_vector.z;
}

Vector3D Vector3D::cross_product(const Vector3D& _vector) const {

	return Vector3D(y*_vector.z - z*_vector.y, z*_vector.x - x*_vector.z,x*_vector.y - y*_vector.x);
}

Vector3D Vector3D::scalar_product(const double _value) const {
	return Vector3D(x*_value,y*_value,z*_value);
}

Vector3D Vector3D::normalize(void) const{
	Vector3D normalized(*this);
	double mod = normalized.dot_product(normalized);
	if(mod != 0.0) { 
		normalized = normalized.scalar_product(1.0/std::sqrt(mod));
	
	}
	return normalized;
}

Vector3D Vector3D::sub_vect(const Vector3D& _vector) const {
	return Vector3D(x-_vector.x,
								y-_vector.y,
								z-_vector.z);
}

const double Vector3D::length(void) const {
	return std::sqrt(this->dot_product(*this));
}

double Vector3D::distance(const Vector3D& _vector) const {
	return std::sqrt((x - _vector.x)*(x - _vector.x) + (y - _vector.y)*(y - _vector.y) + (z - _vector.z)*(z - _vector.z));
}

Vector3D& Vector3D::operator=(const Vector3D& _vector) {
	if(this != &_vector) {
		x = _vector.x;
		y = _vector.y;
		z = _vector.z;
	}
	return *this;
}

bool Vector3D::operator==(const Vector3D& _vector) {
	if((x == _vector.x) && (y == _vector.y) && (z == _vector.z)) return true;
	else return false;
}

const double Vector3D::operator*(const Vector3D& _vector) const {
	return this->dot_product(_vector);
}

const Vector3D Vector3D::operator*(const double _value) const {
	return this->scalar_product(_value);
}

const Vector3D Vector3D::operator+(const Vector3D& _vector) const {
	return Vector3D(x + _vector.x,y + _vector.y,z + _vector.z);
}

const double Vector3D::operator[](const int& _index) const {
	switch(_index) {
		case 1: return x;
		case 2: return y;
		case 3: return z;
		default: return -1.0;
	}
}

const Vector3D Vector3D::operator-(void) const {
	return Vector3D(-x,-y,-z);
}

const Vector3D Vector3D::operator-(const Vector3D& _vector) const {
	return sub_vect(_vector);
}
}
